part of '../repository.dart';

const _kCustomLexicalItemTranscriptionKey = 'transcription';

const _kCustomLexicalItemTypeValue = 'custom_lexical_item';

class _CustomLexicalItemDto extends Equatable implements _LexicalItemDto {
  const _CustomLexicalItemDto._internal({
    required this.id,
    required this.title,
    required this.translation,
    required this.useCaseDtos,
    required this.progressDto,
    required this.excluded,
    required this.transcription,
  });

  @override
  final String id;

  @override
  final String title;

  @override
  final String translation;

  @override
  final BuiltList<_UseCaseDto> useCaseDtos;

  @override
  final _LexicalItemProgressDto? progressDto;

  @override
  final bool excluded;

  final String? transcription;

  @override
  List<Object?> get props {
    return [
      id,
      title,
      translation,
      useCaseDtos,
      progressDto,
      excluded,
      transcription,
    ];
  }

  @override
  String get type => _kCustomLexicalItemTypeValue;

  factory _CustomLexicalItemDto.fromJson(Map<String, dynamic> json) {
    final useCaseMaps = List.castFrom<dynamic, Map>(json[_kLexicalItemUseCasesKey]);

    final useCaseDtos = useCaseMaps.map((useCaseMap) {
      final useCaseJson = Map.castFrom<dynamic, dynamic, String, dynamic>(useCaseMap);
      return _UseCaseDto.fromJson(useCaseJson);
    }).toBuiltList();

    _LexicalItemProgressDto? progressDto;

    final lexicalItemProgressMap = json[_kLexicalItemProgressKey];

    if (lexicalItemProgressMap != null) {
      final lexicalItemProgressJson =
          Map.castFrom<dynamic, dynamic, String, dynamic>(lexicalItemProgressMap);

      progressDto = _LexicalItemProgressDtoFactory().fromJson(lexicalItemProgressJson);
    }

    return _CustomLexicalItemDto._internal(
      id: json[_kLexicalItemIdKey],
      title: json[_kLexicalItemTitleKey],
      translation: json[_kLexicalItemTranslationKey],
      transcription: json[_kCustomLexicalItemTranscriptionKey],
      useCaseDtos: useCaseDtos,
      progressDto: progressDto,
      excluded: json[_kLexicalItemExcludedKey],
    );
  }

  factory _CustomLexicalItemDto.fromEntity(CustomLexicalItem customLexicalItem) {
    final useCaseDtos = customLexicalItem.useCases.map((useCase) {
      return _UseCaseDto.fromEntity(useCase);
    }).toBuiltList();

    _LexicalItemProgressDto? progressDto;

    if (customLexicalItem.progress != null) {
      progressDto = _LexicalItemProgressDtoFactory().fromEntity(customLexicalItem.progress!);
    }

    return _CustomLexicalItemDto._internal(
      id: customLexicalItem.id,
      title: customLexicalItem.title,
      translation: customLexicalItem.translation,
      transcription: customLexicalItem.transcription,
      useCaseDtos: useCaseDtos,
      progressDto: progressDto,
      excluded: customLexicalItem.excluded,
    );
  }

  @override
  Map<String, dynamic> toJson() {
    final useCaseJsons = useCaseDtos.map((useCaseDto) {
      return useCaseDto.toJson();
    }).toList();

    final json = {
      _kLexicalItemTypeKey: type,
      _kLexicalItemIdKey: id,
      _kLexicalItemTitleKey: title,
      _kLexicalItemTranslationKey: translation,
      _kCustomLexicalItemTranscriptionKey: transcription,
      _kLexicalItemUseCasesKey: useCaseJsons,
      _kLexicalItemExcludedKey: excluded,
    };

    if (progressDto != null) {
      json[_kLexicalItemProgressKey] = progressDto!.toJson();
    }

    return json;
  }

  @override
  CustomLexicalItem toEntity() {
    final useCases = useCaseDtos.map((useCaseDto) {
      return useCaseDto.toEntity();
    }).toBuiltList();

    return CustomLexicalItem(
      id: id,
      title: title,
      translation: translation,
      transcription: transcription,
      useCases: useCases,
      progress: progressDto?.toEntity(),
      excluded: excluded,
    );
  }
}
